/**
 * 
 */
package ro.dta.idbi.patterns.primitives;

import java.util.EnumSet;
import java.util.Hashtable;

import ro.dta.idbi.interfaces.IPrimitiveParser;
import ro.dta.idbi.interfaces.IntegrationOperation;
import ro.dta.idbi.model.AbstractPrimitivePattern;
import ro.dta.idbi.model.RenameColumnParser;
import ro.dta.idbi.model.RenameFkParser;
import ro.dta.idbi.model.RenamePkParser;
import ro.dta.idbi.model.RenameTableParser;
import uk.ac.ic.doc.automed.IntegrityException;
import uk.ac.ic.doc.automed.NotFoundException;
import uk.ac.ic.doc.automed.reps.Schema;
import uk.ac.ic.doc.automed.reps.SchemaObject;
import uk.ac.ic.doc.automed.reps.TypeMismatchException;

/**
 * <b>Primitive transformation to remame a construct</b><br />
 * 
 * Example of use:<br />
 * 
 * <code>rename(table:&lt;&lt;oldTable&gt;&gt;, table:&lt;&lt;newTable&gt;&gt;)</code><br />
 * <code>rename(column:&lt;&lt;table,oldCol&gt;&gt;, column:&lt;&lt;table,newCol&gt;&gt;)</code>
 * <br />
 * 
 * @author Tudor Dobrila
 * 
 */
public class RenamePrimitive extends AbstractPrimitivePattern {

	/**
	 * Name of the pattern
	 */
	public static final String NAME = "Rename";

	/**
	 * Description of the pattern
	 */
	public static final String DESCRIPTION = "Rename an SQL construct";

	/**
	 * Name of the command associated with the pattern
	 */
	public static final String COMMAND = "rename";

	/**
	 * Integration phase during which the command is applied
	 */
	public static final EnumSet<IntegrationOperation> OPERATION = EnumSet.of(
			IntegrationOperation.CONFORMING, IntegrationOperation.MERGING);

	/**
	 * Rename construct class constructor
	 * 
	 * Used to rename either a table or a column
	 * 
	 * @param schemaName
	 *            Name of source schema on which the transformation will be
	 *            applied
	 */
	public RenamePrimitive(final String schemaName) throws NotFoundException, IntegrityException {
		this(Schema.getSchema(schemaName));
	}

	/**
	 * Rename construct class constructor
	 * 
	 * Used to rename either a table or a column
	 * 
	 * @param sourceSchema
	 *            Source schema on which the transformation will be applied
	 */
	public RenamePrimitive(final Schema sourceSchema) throws NotFoundException, IntegrityException {
		super(sourceSchema, COMMAND);

		parsers = new Hashtable<String, IPrimitiveParser>();
		parsers.put("renametable", new RenameTableParser());
		parsers.put("renamecolumn", new RenameColumnParser());
		parsers.put("renameprimarykey", new RenamePkParser());
		parsers.put("renameforeignkey", new RenameFkParser());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ro.dta.idbi.patterns.TransformationPattern#execute(java.lang.String)
	 */
	@Override
	public Schema execute(final String trans) throws NotFoundException, TypeMismatchException,
			IntegrityException {
		super.execute(trans);

		Schema crtSchema = sourceSchema;

		String type = (String) construct.get("type");
		SchemaObject origObj = sourceSchema.getSchemaObject((String) construct.get("old"));;
		Object[] objDef = origObj.getSchemeDefinition();;
		
		if ("table".equals(type)) {
			String newName = parseTableName((String) construct.get("new"));
			objDef[0] = newName;
		} else if ("column".equals(type)) {
			String newName = parseColName((String) construct.get("new")).getValue();
			objDef[1] = newName;
		} else if ("primarykey".equals(type) || "foreignkey".equals(type)) {
			String newName = (String) construct.get("new");
			objDef[0] = newName;
		}
		
		crtSchema = crtSchema.applyRenameTransformation(origObj, objDef);

		return crtSchema;
	}

}
